package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.ServiceItemMapper;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 养修服务项Service业务层处理
 * 
 * @author wolfcode
 * @date 2021-05-14
 */
@Service
public class ServiceItemServiceImpl implements IServiceItemService
{
    @Autowired
    private ServiceItemMapper serviceItemMapper;
    @Autowired
    private ICarPackageAuditService carPackageAuditService;
    @Autowired
    private IProcessService processService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;

    /**
     * 查询养修服务项
     * 
     * @param id 养修服务项ID
     * @return 养修服务项
     */
    @Override
    public ServiceItem selectServiceItemById(Long id)
    {
        return serviceItemMapper.selectServiceItemById(id);
    }

    /**
     * 查询养修服务项列表
     * 
     * @param serviceItem 养修服务项
     * @return 养修服务项
     */
    @Override
    public List<ServiceItem> selectServiceItemList(ServiceItem serviceItem)
    {
        return serviceItemMapper.selectServiceItemList(serviceItem);
    }

    /**
     * 新增养修服务项
     * 
     * @param serviceItem 养修服务项
     * @return 结果
     */
    @Override
    public int insertServiceItem(ServiceItem serviceItem)
    {
        serviceItem.setCreateTime(DateUtils.getNowDate());
        if(ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);//设置初始化
        }
        return serviceItemMapper.insertServiceItem(serviceItem);
    }

    /**
     * 修改养修服务项
     * 
     * @param serviceItem 养修服务项
     * @return 结果
     */
    @Override
    public int updateServiceItem(ServiceItem serviceItem)
    {
        ServiceItem oldObj = selectServiceItemById(serviceItem.getId());
        //处于上架状态的商品不能修改
        if(ServiceItem.SALESTATUS_ON.equals(oldObj.getSaleStatus())){
            throw new BusinessException("上架服务项目不能修改，请下架后再修改");
        }else if(ServiceItem.AUDITSTATUS_AUDITING.equals(oldObj.getAuditStatus())){
            throw new BusinessException("服务项目正在审核中,不可修改");
        }
        //如果是审核通过，此时修改，需要将其状态变更为初始化
        if(ServiceItem.AUDITSTATUS_APPROVED.equals(oldObj.getAuditStatus())){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }
        serviceItem.setVersion(oldObj.getVersion());
        return serviceItemMapper.updateServiceItem(serviceItem);
    }
    /**
     * 删除养修服务项对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteServiceItemByIds(String ids)
    {
        return serviceItemMapper.deleteServiceItemByIds(Convert.toStrArray(ids));
    }
    /**
     * 下架
     *
     * @param id 需要下架的服务项ID
     * @return
     */
    @Override
    public int saleOff(Long id) {
        return serviceItemMapper.changeSaleStatus(id,ServiceItem.SALESTATUS_OFF);
    }
    /**
     * 上架
     * @param id 需要上架的服务ID
     * @return
     */
    @Override
    public int saleOn(Long id) {
        ServiceItem serviceItem = selectServiceItemById(id);
        //如果不是套餐，可以直接上架
        //如果是套餐，只有审核成功才能上架
        if(ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())
                && !ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())){
            throw new BusinessException("套餐服务项需要审核通过之后才能上架");
        }
        return serviceItemMapper.changeSaleStatus(id,ServiceItem.SALESTATUS_ON);
    }
    /**
     * 查询上家的养修服务项列表
     *
     * @param serviceItem 养修服务项
     * @return 养修服务项集合
     */
    @Override
    public List<ServiceItem> selectAllSaleOnList(ServiceItem serviceItem) {
        return serviceItemMapper.selectAllSaleOnList(serviceItem);
    }

    /**
     * 发起审核流程
     * @param id
     * @return
     */
    @Override
    @Transactional
    public int startAudit(Long id) {
        //发起审核流程
        //1. 通过传进来的id查询养修服务项是否是套餐&&是否是初始化状态
        ServiceItem serviceItem = serviceItemMapper.selectServiceItemById(id);
        if(serviceItem.getCarPackage() != 1 || serviceItem.getAuditStatus() != 0){
            throw new BusinessException("非法操作,只有是套餐和初始化状态服务项才能发起审核");
        }

        //2. 将审核状态更新为审核中
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_AUDITING);
        serviceItemMapper.updateServiceItem(serviceItem);

        //3. 通过id查询养修服务项信息,封装到CarPackageAudit对象(审核列表对象)的JSON中(转化为JSON格式)
        CarPackageAudit carPackageAudit = new CarPackageAudit();
        carPackageAudit.setServiceItemInfo(JSON.toJSONString(serviceItem)); //快照(存档)



        //4. 将审核发起创建人封装到CarPackageAudit对象中 (创建时间不需要插入数据库会生成)
        carPackageAudit.setCreateBy(ShiroUtils.getUserId().toString()); //当前登陆用户id

        //5. 将CarPackageAudit对象插入到t_car_package_audit表中(审核列表) ,现在插入是为了获取主键id作为流程实例的businessKey
        carPackageAuditService.insertCarPackageAudit(carPackageAudit);

        //6. 发起流程实例,将流程定义id,businessKey,money(养修服务项审核金额)作为参数传入
        String businessKey = carPackageAudit.getId().toString();
        HashMap<String, Object> variables = new HashMap<>();
        variables.put("money",serviceItem.getDiscountPrice().longValue());
        ProcessInstance processInstance = processService.startProcessInstance(CarPackageAudit.DEFINITION_KEY, businessKey, variables);

        //7. 通过流程实例id获取当前任务节点id
        Task currentTask = processService.selectTaskByProcessInstanceId(processInstance.getId());
        String nodeKey = currentTask.getTaskDefinitionKey();//节点id

        //8. 通过任务节点id获取审核人列表
        List<SysUser> auditors = definitionNodeService.selectAuditorsByTaskDefinitionKey(nodeKey);

        //9. 将审核人列表设置到节点候选人中
        ArrayList<String> auditorsName = new ArrayList<>();
        for (SysUser auditor : auditors) {
            processService.addCandidateUser(currentTask,auditor.getUserId());
            auditorsName.add(auditor.getUserName());
        }
        //10. 将审核人名称和流程实例id设置到CarPackageAudit对象中
        carPackageAudit.setAuditors(JSON.toJSONString(auditorsName));
        carPackageAudit.setInstanceId(processInstance.getProcessInstanceId());
        //11. 更新CarPackageAudit对象(update到表中)
        carPackageAuditService.updateCarPackageAudit(carPackageAudit);

        return 1;
    }

    @Override
    public void updateServiceItemNoCondition(ServiceItem serviceItem) {
        serviceItemMapper.updateServiceItemNoCondition(serviceItem);
    }


}
